﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Windows;
using System.Windows.Input;
using Chess.Client.Model;
using Chess.Common;
using MvvmToolkit.Commands;
using MvvmToolkit.ViewModels;

namespace Chess.Client.ViewModel
{
    internal class ProfileViewModel : ViewModelBase
    {
        public ProfileViewModel(ClientService clientService, ProfileModel model)
        {
            _model = model;
            _clientService = clientService;
        }

        private IPAddress Localhost { get { return IPAddress.Parse("127.0.0.1"); } }
        private ProfileModel _model;
        private bool _connected;

        private DelegateCommand _signIn;
        private DelegateCommand _register;
        private DelegateCommand _signOut;

        private ClientService _clientService;

        public ClientService ClientService { get { return _clientService; } }

        public string Login
        {
            get { return _model.Login; }
            set
            {
                _model.Login = value;
                OnPropertyChanged("Login");
            }
        }

        public string Password
        {
            get { return _model.Password; }
            set
            {
                _model.Password = value;
                OnPropertyChanged("Password");
            }
        }
        public string RegisterLogin
        {
            get { return _model.RegisterLogin; }
            set
            {
                _model.RegisterLogin = value;
                OnPropertyChanged("RegisterLogin");
            }
        }
        public string RegisterPassword
        {
            get { return _model.RegisterPassword; }
            set
            {
                _model.RegisterPassword = value;
                OnPropertyChanged("RegisterPassword");
            }
        }
        public string RegisterConfirmPassword
        {
            get { return _model.RegisterConfirmPassword; }
            set
            {
                _model.RegisterConfirmPassword = value;
                OnPropertyChanged("RegisterConfirmPassword");
            }
        }

        public IPAddress ServerIpAddress
        {
            get { return _model.ServerIpAddress ?? Localhost; }
            set
            {
                _model.ServerIpAddress = value;
                OnPropertyChanged("ServerIpAddress");
            }
        }

        public string StatusBar
        {
            get
            {
                string message;
                if (!string.IsNullOrEmpty(Login))
                {
                    message = string.Format("Connected to {0}:{1}.", ServerIpAddress, 5000);
                }
                else
                    message = "Server connection is not established.";
                return message;
            }
        }

        public bool Connected
        {
            get { return _connected; }
            set
            {
                _connected = value;
                OnPropertyChanged("Connected");
                OnPropertyChanged("SignInButtonText");
                OnPropertyChanged("SignInOutCommand");
                OnPropertyChanged("StatusBar");
            }
        }

        public ICommand SignInOutCommand
        {
            get
            {
                DelegateCommand command;
                if (!Connected)
                {
                    if (_signIn == null)
                        _signIn = new DelegateCommand(SignIn);
                    command = _signIn;
                }
                else
                {
                    if(_signOut == null)
                        _signOut = new DelegateCommand(SignOut);
                    command = _signOut;
                }
                return command;
            }
        }

        public ICommand RegisterCommand
        {
            get { return _register ?? (_register = new DelegateCommand(Register)); }
        }

        public string SignInButtonText
        {
            get { return Connected ? "Sign out" : "Sign in"; }
        }

        private async void SignIn()
        {
            try
            {
                await _clientService.Connect(ServerIpAddress, 5000);

                var answerPackage = await _clientService.Login(Login, Password);
                string message = "";
                switch (answerPackage.Answer)
                {
                    case LoginAnswerType.Ok:
                        message = string.Format("User {0} was logged on server.", Login);
                        Connected = true;
                        //OnPropertyChanged("SignInButtonText");
                        //OnPropertyChanged("SignInOutCommand");
                        //OnPropertyChanged("StatusBar");
                        break;
                    case LoginAnswerType.PasswordFailed:
                        message = "Неверный пароль.";
                        break;
                    case LoginAnswerType.UserNotExists:
                        message = string.Format("Пользователь {0} не зарегистрирован.", Login);
                        break;
                }
                MessageBox.Show(message);
            }
            catch(Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        private async void Register()
        {
            var login = RegisterLogin;
            var password = RegisterPassword;
            var confirmPassword = RegisterConfirmPassword;

            if (password == confirmPassword)
            {
                _clientService.Connect(ServerIpAddress, 5000);
                var answerPackage = await _clientService.Register(login, password);
                string message = "";
                switch (answerPackage.Answer)
                {
                    case RegisterAnswerType.Ok:
                        message = "Registration is successful.";
                        break;
                    case RegisterAnswerType.UserExists:
                        message = "The user already exists.";
                        break;
                }
                MessageBox.Show(message);
            }
        }

        private async void SignOut()
        {
            Login = null;
            Password = null;
            Connected = false;
            await _clientService.Logout();
        }
    }
}
